/*
 * Copyright (c) 2011.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.skavookie.expressions

/**
 * Created by IntelliJ IDEA.
 * User: joshua
 * Date: 5/24/11
 * Time: 11:41 AM
 * To change this template use File | Settings | File Templates.
 */

/**
 * All expressions derive from this.
 *
 *
 */
trait Expr[T] {
	def toString: String
	def equals(other: Any): Boolean
	def hashCode: Int
}

trait TWithManifest[T] extends Expr[T] {
	val manifest: Manifest[T]
	def getManifest = manifest
}
trait TLiteral[T] extends TWithManifest[T] {
	val literal: T
	def getLiteral = literal
}
trait TGet[T] extends TWithManifest[T] {
	val key: KeyType
}
trait TSet[T] extends TWithManifest[T] {
	val key: KeyType
	val value: Expr[T]
}

trait Packable[T] extends Expr[T] {
	type Out[U] <: Expr[U]
	type In[U] <: Expr[U]
	def pack[U](args: In[U]*): Option[Out[U]]
}

trait TExprWrapper[T] extends Expr[T] {
	def getExpr: Expr[T]
}

/** A trait for marking casts from T to U */
trait TCast[T,U] extends TWithManifest[U] {
	val oldValue: Expr[T]
	def getCast: Expr[U]
}

case class LiteralExpr[T](literal: T)(implicit val manifest: Manifest[T]) extends Expr[T] with TLiteral[T]
case class GetExpr[T](key: KeyType)(implicit val manifest: Manifest[T]) extends Expr[T] with TGet[T]
case class SetExpr[T](key: KeyType, value: Expr[T])(implicit val manifest: Manifest[T]) extends Expr[T] with TSet[T]
